/*
 * The contents of this web application are subject to the Mozilla Public License Version 
 * 1.1 (the "License"); you may not use this web application except in compliance with 
 * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
 * for the specific language governing rights and limitations under the License.
 * 
 * The Original Code is owned by and the Initial Developer of the Original Code is 
 * Composite A/S (Danish business reg.no. 21744409). All Rights Reserved
 * 
 * Section 11 of the License is EXPRESSLY amended to include a provision stating 
 * that any dispute, including but not limited to disputes related to the enforcement 
 * of the License, to which Composite A/S as owner of the Original Code, as Initial 
 * Developer or in any other role, becomes a part to shall be governed by Danish law 
 * and be initiated before the Copenhagen City Court ("K�benhavns Byret")            
 */

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Composite.Core.Threading;
using Composite.Data;


namespace Composite.Core.Implementation
{
    /// <summary>
    /// Documentation pending
    /// </summary>
    public class DataConnectionImplementation : DataConnectionBase, IDisposable
    {
        private IDisposable _threadDataManager;
        private readonly DataScope _dataScope;


        /// <summary>
        /// Stateless constructor. This is used when implementations of static methods needs to be called
        /// Used when New and AllLocales are called
        /// </summary>
        public DataConnectionImplementation()
        {
            InitializeThreadData();
            InitializeScope();
        }


        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="locale"></param>
        public DataConnectionImplementation(PublicationScope scope, CultureInfo locale)
        {
            InitializeThreadData();
            InitializeScope(scope, locale);

            _dataScope = new DataScope(this.DataScopeIdentifier, locale);
        }

        private void InitializeThreadData()
        {
            _threadDataManager = ThreadDataManager.EnsureInitialize();
        }

        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <returns></returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "This is what we want")]
        public virtual IQueryable<TData> Get<TData>()
            where TData : class, IData
        {
        //    using (new DataScope(this.DataScopeIdentifier, this.Locale))
            {
                return DataFacade.GetData<TData>();
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <param name="item"></param>
        /// <returns></returns>
        public virtual TData Add<TData>(TData item)
            where TData : class, IData
        {
         //   using (new DataScope(this.DataScopeIdentifier, this.Locale))
            {
                return DataFacade.AddNew<TData>(item);
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <param name="items"></param>
        /// <returns></returns>
        public virtual IList<TData> Add<TData>(IEnumerable<TData> items)
            where TData : class, IData
        {
         //   using (new DataScope(this.DataScopeIdentifier, this.Locale))
            {
                return DataFacade.AddNew<TData>(items);
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <param name="item"></param>
        public virtual void Update<TData>(TData item)
            where TData : class, IData
        {
         //   using (new DataScope(this.DataScopeIdentifier, this.Locale))
            {
                DataFacade.Update(item);
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <param name="items"></param>
        public virtual void Update<TData>(IEnumerable<TData> items)
            where TData : class, IData
        {
         //   using (new DataScope(this.DataScopeIdentifier, this.Locale))
            {
                DataFacade.Update(items);
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <param name="item"></param>
        public virtual void Delete<TData>(TData item)
            where TData : class, IData
        {
          //  using (new DataScope(this.DataScopeIdentifier, this.Locale))
            {
                DataFacade.Delete<TData>(item);
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <param name="items"></param>
        public virtual void Delete<TData>(IEnumerable<TData> items)
            where TData : class, IData
        {
          //  using (new DataScope(this.DataScopeIdentifier, this.Locale))
            {
                DataFacade.Delete<TData>(items);
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <typeparam name="TData"></typeparam>
        /// <returns></returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "New", Justification = "This is what we want")]
        public virtual TData New<TData>()
            where TData : class, IData
        {
            return DataFacade.BuildNew<TData>();
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        public virtual PublicationScope CurrentPublicationScope
        {
            get
            {
                return this.PublicationScope;
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        public virtual CultureInfo CurrentLocale
        {
            get
            {
                return this.Locale;
            }
        }


        /// <summary>
        /// Documentation pending
        /// </summary>
        public virtual IEnumerable<CultureInfo> AllLocales
        {
            get
            {
                return DataLocalizationFacade.ActiveLocalizationCultures;
            }
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }



        /// <exclude />
        ~DataConnectionImplementation()
        {
            Dispose(false);
        }



        /// <summary>
        /// Documentation pending
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                _dataScope.Dispose();

                _threadDataManager.Dispose();
            }
        }
    }
}
